/*
 * Copyright 2017 JessYan
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.kingeid.basic.base.activity;

import android.graphics.Color;
import android.os.Bundle;

import androidx.annotation.AnimRes;
import androidx.annotation.ColorInt;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;

import com.blankj.utilcode.util.BarUtils;
import com.trello.rxlifecycle3.android.ActivityEvent;
import com.kingeid.basic.R;
import com.kingeid.basic.base.delegate.IActivity;
import com.kingeid.basic.base.fragment.BaseFragment;
import com.kingeid.basic.integration.cache.Cache;
import com.kingeid.basic.integration.cache.CacheType;
import com.kingeid.basic.integration.lifecycle.ActivityLifecycleable;
import com.kingeid.basic.mvp.IPresenter;
import com.kingeid.basic.utils.Utils;

import javax.inject.Inject;

import butterknife.ButterKnife;
import butterknife.Unbinder;
import io.reactivex.subjects.BehaviorSubject;
import io.reactivex.subjects.Subject;


public abstract class BaseActivity<P extends IPresenter> extends AppCompatActivity implements IActivity, ActivityLifecycleable {
    protected final String TAG = this.getClass().getSimpleName();
    private final BehaviorSubject<ActivityEvent> mLifecycleSubject = BehaviorSubject.create();
    private Cache<String, Object> mCache;
    private Unbinder mUnbinder;

    @Inject
    @Nullable
    protected P mPresenter;//如果当前页面逻辑简单, Presenter 可以为 null

    @NonNull
    @Override
    public synchronized Cache<String, Object> provideCache() {
        if (mCache == null) {
            mCache = Utils.obtainAppComponentFromContext(this).cacheFactory().build(CacheType.ACTIVITY_CACHE);
        }
        return mCache;
    }

    @NonNull
    @Override
    public final Subject<ActivityEvent> provideLifecycleSubject() {
        return mLifecycleSubject;
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        try {
            int layoutResID = getContentView();
            //如果initView返回0,框架则不会调用setContentView(),当然也不会 Bind ButterKnife
            if (layoutResID != 0) {
                setContentView(layoutResID);
                beforeBindView();
                //绑定到butterknife
                mUnbinder = ButterKnife.bind(this);
                initWidget(savedInstanceState);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        initData(savedInstanceState);

        if (useImmersion()) {
            BarUtils.setStatusBarColor(this, getStatusBarColor(), true);
            BarUtils.setStatusBarLightMode(this, getStatusBarColor() == Color.WHITE);
            if (userDefaultStatusBarHeightMargin()) {
                BarUtils.addMarginTopEqualStatusBarHeight(getWindow().getDecorView().findViewById(android.R.id.content));
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mUnbinder != null && mUnbinder != Unbinder.EMPTY)
            mUnbinder.unbind();
        this.mUnbinder = null;
        if (mPresenter != null)
            mPresenter.onDestroy();//释放资源
        this.mPresenter = null;
    }

    @Override
    public void onBackPressed() {
        if (!getSupportFragmentManager().popBackStackImmediate()) {
            finish();
        }
    }

    /**
     * 是否使用eventBus,默认为使用(true)，
     *
     * @return
     */
    @Override
    public boolean useEventBus() {
        return true;
    }

    /**
     * 这个Activity是否会使用Fragment,框架会根据这个属性判断是否注册{@link FragmentManager.FragmentLifecycleCallbacks}
     * 如果返回false,那意味着这个Activity不需要绑定Fragment,那你再在这个Activity中绑定继承于 {@link BaseFragment} 的Fragment将不起任何作用
     *
     * @return
     */
    @Override
    public boolean useFragment() {
        return true;
    }

    @Override
    public void beforeBindView() {

    }

    /**
     * 是否同化状态栏
     */
    @Override
    public boolean useImmersion() {
        return true;
    }

    /**
     * 是否使用默认的状态栏高度margin
     */
    @Override
    public boolean userDefaultStatusBarHeightMargin() {
        return true;
    }

    /**
     * 状态栏颜色,默认主题色
     */
    public @ColorInt
    int getStatusBarColor() {
        return getResources().getColor(R.color.colorPrimary);
    }


    protected void addFragment(@IdRes int containerViewId, @NonNull Fragment fragment) {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.add(containerViewId, fragment);
        ft.commitAllowingStateLoss();
    }

    public void addFragment(@IdRes int containerViewId, @NonNull Fragment fragment, @Nullable String tag) {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.add(containerViewId, fragment, tag);
        ft.commitAllowingStateLoss();
    }

    public void addFragment(@NonNull Fragment fragment, @Nullable String tag) {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.add(fragment, tag);
        ft.commitAllowingStateLoss();
    }

    public void replaceFragment(@IdRes int containerViewId, @NonNull Fragment fragment) {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.replace(containerViewId, fragment);
        ft.commitAllowingStateLoss();
    }

    public void replaceFragment(@IdRes int containerViewId, @NonNull Fragment fragment, @Nullable String tag) {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.replace(containerViewId, fragment, tag);
        ft.commitAllowingStateLoss();
    }

    public void removeFragment(@NonNull Fragment fragment) {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.remove(fragment);
        ft.commitAllowingStateLoss();
    }

    /**
     * 显示Fragment
     */
    protected void showFragment(Fragment fragment) {
        showFragment(fragment, 0, 0);
    }

    /**
     * 以动画方式显示Fragment
     *
     * @param fragment 要显示的Fragment
     * @param enter    进入动画
     * @param exit     退出动画
     */
    protected void showFragment(Fragment fragment, @AnimRes int enter, @AnimRes int exit) {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.setCustomAnimations(enter, exit);
        ft.show(fragment);
        ft.commitAllowingStateLoss();
    }

    /**
     * 隐藏Fragment
     */
    protected void hideFragment(Fragment fragment) {
        hideFragment(fragment, 0, 0);
    }

    /**
     * 以动画方式隐藏Fragment
     *
     * @param fragment 要显示的Fragment
     * @param enter    进入动画
     * @param exit     退出动画
     */
    protected void hideFragment(Fragment fragment, @AnimRes int enter, @AnimRes int exit) {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.setCustomAnimations(enter, exit);
        ft.hide(fragment);
        ft.commitAllowingStateLoss();
    }

}
